
// 作用域分为：
// 1.全局作用域：

// 2.函数作用域

// 3.块级作用域(es6):
// 大括号：
if(true){
	let x=100
}
console.log(x) //会报错

// 自由变量：

// 一个变量在当前作用域没有定义，但被使用了

// 1.向上级作用域，一层一层寻找，直到找到
// 2.如果到全局作用域没找到，则报错 xx is not defined


// 闭包：

// 作用域应用的特殊情况，两种表现：
// 1.函数作为返回值被返回
function create(){
	const a=100
	return function(){
		console.log(a)
	}
}
const fn=create
const a=200
fn()  // 100


// 2.函数作为参数被传递

function print(fn){
	let a=200
	fn()
}
let a=100
function fn(){
	console.log(a)
}
print(fn)  //100

//闭包:所有自由变量的查找，是在函数定义的地方，向上级作用域查找，不是在执行的地方查找！

 /**	
  * this
  * 
  */
//  三种调用方式：
// 1.作为普通函数调用
// 2.使用call.apply.bind调用,传入什么就绑定什么
// 3.作为对象方法被调用
// 4.在class方法中调用(实例本身)
// 5.箭头函数

// this的取值是在函数执行的时候确认的，不是在定义的时候确认的！
const dd={
	name:'dd',
	sayHI(){
		// this即指当前对象
		console.log(this)
	},
	wait(){
		setTimeout(function(){
			// this===window
			console.log(this)
		});	
	},
	waitAgain(){
		setTimeout(()=>{
			// this即指当前对象,箭头函数内this的取值是取他上级作用域的值
			console.log(this)
		})	
	}
}






class People{
	constructor(name){
		this.name=name;
		this.age=20
	}
	sayHi(){
		console.log(this)
	}
}
const dd=new People('张三')
dd.sayHi() //张三对象



// 闭包的应用：
// 1.隐藏数据,提供api
function createCache(){
	const data={}
	return {
		set:function(key,val){
			data[key]=val
		},
		get:function(key){
			return data[key]
		}
	}
}
const c=createCache()
c.set('a',100)
console.log(c.get('a'))



let a=100
function test(){
	alert(a)
	a=10; //a是全局变量
	alert(a)
}
test()
alert(a)

// 依次打印出100,10,10




// 创建十个<a>标签，点击时候弹出对应序号：

// let i,a;
// for(i=0;i<10;i++){
// 	a=document.createElement('a');
// 	a.innerHTML=i + '<br>'
// 	a.addEventListener('click',function(){
// 		e.preventDefault();
// 		// 点击的时候循环已经做完
// 		alert(i);
// 	})
// 	document.body.appendChild(a)
// }


let a;
for(let i=0;i<10;i++){
	// 改变i的作用域到块级,每次for循环执行的时候都会不一样
	a=document.createElement('a');
	a.innerHTML=i + '<br>'
	a.addEventListener('click',function(e){
		e.preventDefault();
		// 点击的时候循环已经做完
		alert(i);
	})
	document.body.appendChild(a)
}

// 获取多个数字中的最大值
Math.max(10,20,30,10)

function max(){
	const nums=Array.prototype.slice.call(arguments); //变成数组
	let max=0;
	nums.forEach(element => {
		if(element>max){
			max=element
		}
	});
	return max
}
